package com.le.tester.webpage.lock;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 描述：线程保护过头了有点，其实，在修改数据的时候才需要获取锁的，可以的场景是，可以允许多个线程同时的读，但是在写的时候，只能有一个线程在写，其他的线程必须在等待
 * 我们可以使用lock中的readWriteLock中的readwriteLock;new ReentrantReadWriteLock();
 * 保证1.只允许一个线程在写入数据，其他的线程在等待（不能写入也不能读取）
 * 2.在没有写入的情况，允许多个线程进行读取数据
 * 3.是对用一个数据，很多线程需要去读取，然后很少的线程去修改这个数据
 * 4.弊端就是在读取数据的时候，获取不到这个写入的锁，需要等待读取就是，可以看出这是一个悲观的锁
 * 5.但是在读的时候，可以进行写入的话，就有可能出现数据的不一致了，jdk1.8引入了StampedLock，自己可以做额外的处理
 */
public class CounterReadWrite {

    //集成了read和write
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    //读取数据的锁
    private final Lock readLock = readWriteLock.readLock();

    //写入数据的锁
    private final Lock writeLock = readWriteLock.writeLock();

    private int[] count = new int[10];


    public void increment(int index) {
        //锁住，只能允许一个线程进行写入数据，其他的线程不能进行数据的读取和写入
        writeLock.lock();
        try {
            count[index] += 1;

        } finally {
            writeLock.unlock();
        }

    }

    public int[] get() {
        //要进行数据的读取，那么在使用的就是多个线程可以同时的读取
        readLock.lock();
        try {
            return Arrays.copyOf(count, count.length);
        } finally {
            readLock.unlock();
        }
    }



}
